#include "internal.h"
#include "Accelerometer2D.h"
#include "Accelerometer2D.tmh"
#include "WpdObjectProperties.h" 

const PROPERTYKEY g_SupportedDualAxisProperties[] =
{
    SENSOR_PROPERTY_TYPE,
    SENSOR_PROPERTY_STATE,
    SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL,
    SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
    SENSOR_PROPERTY_FRIENDLY_NAME,
    SENSOR_PROPERTY_DESCRIPTION, 
    SENSOR_PROPERTY_CONNECTION_TYPE,
    WPD_FUNCTIONAL_OBJECT_CATEGORY,
};

const PROPERTYKEY g_SupportedDualAxisDataFields[] =
{
    SENSOR_DATA_TYPE_TIMESTAMP,
    SENSOR_DATA_TYPE_ACCELERATION_X_G,
    SENSOR_DATA_TYPE_ACCELERATION_Y_G,
};

Accelerometer2D::Accelerometer2D(WpdObjectProperties* pWpdObjectProperties): 
	SensorBase(pWpdObjectProperties) 
{
	m_strSensorName		= SENSOR_DUAL_AXIS_FRIENDLY_NAME;
	m_strSensorId		= SENSOR_DUAL_AXIS_ID;
	m_gdSensorUniqueId	= SENSOR_DUAL_AXIS_GUID;
	m_gdSensorCategory	= SENSOR_CATEGORY_MOTION;
	m_gdSensorType		= SENSOR_TYPE_ACCELEROMETER_2D;
}

VOID Accelerometer2D::AddPropertyKeys(
	IPortableDeviceKeyCollection* pKeys)
{
    if (pKeys != NULL)
    {
        for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedDualAxisProperties); dwIndex++)
        {
            pKeys->Add(g_SupportedDualAxisProperties[dwIndex] );
        }
    }
}

VOID Accelerometer2D::AddDataFieldKeys(
	IPortableDeviceKeyCollection* pKeys)
{
    if (pKeys != NULL)
    {
        for (DWORD dwIndex = 0; dwIndex < ARRAYSIZE(g_SupportedDualAxisDataFields); dwIndex++)
        {
            pKeys->Add(g_SupportedDualAxisDataFields[dwIndex] );
        }
    }
}


// Strips the packet header value "616" from the
// packet of accelerometer data. (ie. 616019107 becomes 019107).
__int64 Remove2DAccelPacketHeader(__int64 llData)
{
    __int64 llFinalVal = 0;

    llFinalVal = llData - 616000000;
    return llFinalVal;
}

// Retrieve the 3-digit G-force along the X-Axis. The input value will have
// the form 109000. The first 3 digits are X-Axis values; the latter 3 Y-Axis.
// The first digit is 1 or 0. 1 indicates a negative force vector; 0 positive.
// The last two digits specify the force value ("17" is 1.7Gs; "07" is .7Gs)
float XAxisForce(__int64 llVal)
{
    float fForce = 0.0;
    llVal = llVal/1000;
    if (llVal > 100)
    {
        llVal = llVal - 100; //Remove leading 1
        fForce = (float)llVal/10; //Convert to G-force
        fForce = fForce * (float)-1.0;
    }
    else if (llVal == 100)
        fForce = 0.0;
    else
        fForce = (float)llVal/10;
    return fForce;
}

// Retrieve the 3-digit G-force along the X-Axis. The input value will have
// the form 109000. The first 3 digits are X-Axis values; the latter 3 Y-Axis.
// The first digit is 1 or 0. 1 indicates a negative force vector; 0 positive.
// The last two digits specify the force value ("17" is 1.7Gs; "07" is .7Gs)
float YAxisForce(__int64 llVal)
{
    float fForce = 0.0;
    float fTemp = 0.0;
    int iTemp = 0;

    if (llVal >= 1000) // Remove existing X-force
    {
        iTemp = (int)llVal/1000; //Strip off the last three digits (Y-value)
        fTemp = (float)iTemp * 1000; //Reset to the original X-value
        fForce = (float)llVal - fTemp; //Obtain the Y-component
    }
    else // X-force is zero
    {
        fForce = (float)llVal;
    }
    
    if (fForce > 100.0) // Convert to negative force value
    {
        fForce = fForce - (float)100.0; //Remove leading 1
        fForce = fForce/10; //Convert to G-force
        fForce = fForce * (float)-1.0;
    }
    else if (fForce == 100)
        fForce = 0.0;
    else if (fForce < 100)
        fForce = fForce/10;
    return fForce;
}


HRESULT Accelerometer2D::OnGetDataValues(
    PROPERTYKEY &Key,
    IPortableDeviceValues*         pValues)
{
    HRESULT hr		= S_OK;
	float	fXAccel = 0.0;
    float	fYAccel = 0.0;
    LONGLONG llData = 0;

    // Set G-force data   
    if (IsEqualPropertyKey(Key, SENSOR_DATA_TYPE_ACCELERATION_X_G))
    {
        llData = Remove2DAccelPacketHeader(m_llSensorReading);
        fXAccel = XAxisForce(llData);
        hr = pValues->SetFloatValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, fXAccel);
    }

    if (IsEqualPropertyKey(Key, SENSOR_DATA_TYPE_ACCELERATION_Y_G))
    {
        llData = Remove2DAccelPacketHeader(m_llSensorReading);
        fYAccel = YAxisForce(llData);
        hr = pValues->SetFloatValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, fYAccel);
    }
	return hr;
}